package controller

import (
	"bookmark-web/dao"
	"bookmark-web/logic"
	"bookmark-web/middleware"
	"bookmark-web/models"
	"bookmark-web/utils"
	"log"
	"strconv"

	"github.com/gin-gonic/gin"
)

// SetupAdminRouter 配置后台管理路由
func SetupAdminRouter(api *gin.RouterGroup) {
	// 后台管理路由组，需要管理员权限
	admin := api.Group("/admin")
	admin.Use(middleware.AdminAuthMiddleware())
	{
		// 用户管理
		admin.GET("/users", AdminGetAllUsers)           // 获取所有用户
		admin.GET("/users/:id", AdminGetUserById)       // 根据ID获取用户
		admin.POST("/users", AdminCreateUser)           // 创建用户
		admin.PUT("/users/:id", AdminUpdateUserById)    // 根据ID更新用户
		admin.DELETE("/users/:id", AdminDeleteUserById) // 根据ID删除用户
		admin.PUT("/users/:id/admin", AdminToggleAdmin) // 切换用户管理员身份

		// 分类管理
		admin.GET("/categories", AdminGetAllCategories)          // 获取所有分类
		admin.GET("/categories/:id", AdminGetCategoryById)       // 根据ID获取分类
		admin.DELETE("/categories/:id", AdminDeleteCategoryById) // 根据ID删除分类

		// 书签管理
		admin.GET("/bookmarks", AdminGetAllBookmarks)                   // 获取所有书签
		admin.GET("/bookmarks/:id", AdminGetBookmarkById)               // 根据ID获取书签
		admin.DELETE("/bookmarks/:id", AdminDeleteBookmarkById)         // 根据ID删除书签
		admin.GET("/bookmarks/user/:userId", AdminGetBookmarksByUserId) // 根据用户ID获取书签
	}
}

// AdminGetAllUsers 获取所有用户
// @Summary 获取所有用户
// @Description 获取系统中所有用户
// @Tags 后台管理 - 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} utils.Response "获取成功"
// @Router /admin/users [get]
func AdminGetAllUsers(c *gin.Context) {
	users, err := dao.GetAllUsers()
	if err != nil {
		log.Printf("获取所有用户失败: %v", err)
		utils.Error(c, "获取所有用户失败")
		return
	}

	// 转换为响应格式
	var userResponses []models.UserResponse
	for _, user := range users {
		userResponses = append(userResponses, *user.ToResponse())
	}

	utils.Success(c, "获取所有用户成功", userResponses)
}

// AdminGetUserById 根据ID获取用户
// @Summary 根据ID获取用户
// @Description 根据ID获取用户
// @Tags 后台管理 - 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "用户ID"
// @Success 200 {object} utils.Response "获取成功"
// @Router /admin/users/{id} [get]
func AdminGetUserById(c *gin.Context) {
	id := c.Param("id")
	user, err := dao.GetUserByID(id)
	if err != nil {
		log.Printf("根据ID获取用户失败: %v", err)
		utils.Error(c, "根据ID获取用户失败")
		return
	}

	utils.Success(c, "根据ID获取用户成功", user.ToResponse())
}

// AdminCreateUser 创建用户
// @Summary 创建用户
// @Description 创建用户
// @Tags 后台管理 - 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param data body models.UserRegisterRequest true "用户信息"
// @Success 200 {object} utils.Response "创建成功"
// @Router /admin/users [post]
func AdminCreateUser(c *gin.Context) {
	var req models.UserRegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		log.Printf("参数绑定失败: %v", err)
		utils.InvalidParams(c, "请求参数格式错误")
		return
	}

	// 调用业务逻辑层创建用户
	userResp, err := logic.RegisterUser(&req)
	if err != nil {
		log.Printf("创建用户失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	utils.Success(c, "创建用户成功", userResp)
}

// AdminUpdateUserById 根据ID更新用户
// @Summary 根据ID更新用户
// @Description 根据ID更新用户
// @Tags 后台管理 - 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "用户ID"
// @Param data body models.UserUpdateRequest true "更新信息"
// @Success 200 {object} utils.Response "更新成功"
// @Router /admin/users/{id} [put]
func AdminUpdateUserById(c *gin.Context) {
	idStr := c.Param("id")

	var req models.UserUpdateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		log.Printf("参数绑定失败: %v", err)
		utils.InvalidParams(c, "请求参数格式错误")
		return
	}

	userID, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "用户ID格式错误")
		return
	}

	// 调用业务逻辑层更新用户信息
	userResp, err := logic.UpdateUserById(uint(userID), &req)
	if err != nil {
		log.Printf("修改用户信息失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	utils.Success(c, "修改用户信息成功", userResp)
}

// AdminDeleteUserById 根据ID删除用户
// @Summary 根据ID删除用户
// @Description 根据ID删除用户
// @Tags 后台管理 - 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "用户ID"
// @Success 200 {object} utils.Response "删除成功"
// @Router /admin/users/{id} [delete]
func AdminDeleteUserById(c *gin.Context) {
	id := c.Param("id")

	// 这里需要实现删除用户的逻辑
	// 注意：需要级联删除用户的分类和书签
	// 暂时用简单的实现
	_, err := dao.GetUserByID(id)
	if err != nil {
		log.Printf("根据ID获取用户失败: %v", err)
		utils.Error(c, "根据ID获取用户失败")
		return
	}

	// 调用dao层的删除方法（级联删除用户的分类和书签）
	err = dao.DeleteUserById(id)
	if err != nil {
		log.Printf("删除用户失败: %v", err)
		utils.Error(c, "删除用户失败")
		return
	}

	utils.Success(c, "删除用户成功", nil)
}

// AdminToggleAdmin 切换用户管理员身份
// @Summary 切换用户管理员身份
// @Description 切换用户管理员身份
// @Tags 后台管理 - 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "用户ID"
// @Param is_admin query bool true "是否为管理员"
// @Success 200 {object} utils.Response "操作成功"
// @Router /admin/users/{id}/admin [put]
func AdminToggleAdmin(c *gin.Context) {
	id := c.Param("id")
	isAdminStr := c.Query("is_admin")
	isAdmin, err := strconv.ParseBool(isAdminStr)
	if err != nil {
		utils.InvalidParams(c, "is_admin参数格式错误")
		return
	}

	// 调用DAO更新用户管理员身份
	user, err := dao.GetUserByID(id)
	if err != nil {
		log.Printf("根据ID获取用户失败: %v", err)
		utils.Error(c, "根据ID获取用户失败")
		return
	}

	user.IsAdmin = isAdmin
	err = dao.UpdateUserById(id, *user)
	if err != nil {
		log.Printf("更新用户管理员身份失败: %v", err)
		utils.Error(c, "更新用户管理员身份失败")
		return
	}

	utils.Success(c, "切换用户管理员身份成功", user.ToResponse())
}

// AdminGetAllCategories 获取所有分类
// @Summary 获取所有分类
// @Description 获取系统中所有分类
// @Tags 后台管理 - 分类管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} utils.Response "获取成功"
// @Router /admin/categories [get]
func AdminGetAllCategories(c *gin.Context) {
	// 实现获取所有分类的逻辑
	var categories []models.Category

	// 使用DAO的DB直接查询所有分类
	err := dao.DB.Find(&categories).Error
	if err != nil {
		log.Printf("获取所有分类失败: %v", err)
		utils.Error(c, "获取所有分类失败")
		return
	}

	utils.Success(c, "获取所有分类成功", categories)
}

// AdminGetCategoryById 根据ID获取分类
// @Summary 根据ID获取分类
// @Description 根据ID获取分类
// @Tags 后台管理 - 分类管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "分类ID"
// @Success 200 {object} utils.Response "获取成功"
// @Router /admin/categories/{id} [get]
func AdminGetCategoryById(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "分类ID格式错误")
		return
	}

	var category models.Category
	err = dao.DB.Where("id = ?", uint(id)).First(&category).Error
	if err != nil {
		log.Printf("根据ID获取分类失败: %v", err)
		utils.Error(c, "根据ID获取分类失败")
		return
	}

	utils.Success(c, "根据ID获取分类成功", category)
}

// AdminDeleteCategoryById 根据ID删除分类
// @Summary 根据ID删除分类
// @Description 根据ID删除分类
// @Tags 后台管理 - 分类管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "分类ID"
// @Success 200 {object} utils.Response "删除成功"
// @Router /admin/categories/{id} [delete]
func AdminDeleteCategoryById(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "分类ID格式错误")
		return
	}

	var category models.Category
	err = dao.DB.Where("id = ?", uint(id)).First(&category).Error
	if err != nil {
		log.Printf("根据ID获取分类失败: %v", err)
		utils.Error(c, "根据ID获取分类失败")
		return
	}

	// 使用现有的DeleteCategory函数，传入分类的user_id
	err = dao.DeleteCategory(uint(id), category.UserID)
	if err != nil {
		log.Printf("删除分类失败: %v", err)
		utils.Error(c, "删除分类失败")
		return
	}

	utils.Success(c, "根据ID删除分类成功", nil)
}

// AdminGetAllBookmarks 获取所有书签
// @Summary 获取所有书签
// @Description 获取系统中所有书签
// @Tags 后台管理 - 书签管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} utils.Response "获取成功"
// @Router /admin/bookmarks [get]
func AdminGetAllBookmarks(c *gin.Context) {
	var bookmarks []models.Bookmark

	// 使用DAO的DB直接查询所有书签
	err := dao.DB.Preload("Category").Find(&bookmarks).Error
	if err != nil {
		log.Printf("获取所有书签失败: %v", err)
		utils.Error(c, "获取所有书签失败")
		return
	}

	utils.Success(c, "获取所有书签成功", bookmarks)
}

// AdminGetBookmarkById 根据ID获取书签
// @Summary 根据ID获取书签
// @Description 根据ID获取书签
// @Tags 后台管理 - 书签管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "书签ID"
// @Success 200 {object} utils.Response "获取成功"
// @Router /admin/bookmarks/{id} [get]
func AdminGetBookmarkById(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "书签ID格式错误")
		return
	}

	var bookmark models.Bookmark
	err = dao.DB.Preload("Category").Where("id = ?", uint(id)).First(&bookmark).Error
	if err != nil {
		log.Printf("根据ID获取书签失败: %v", err)
		utils.Error(c, "根据ID获取书签失败")
		return
	}

	utils.Success(c, "根据ID获取书签成功", bookmark)
}

// AdminDeleteBookmarkById 根据ID删除书签
// @Summary 根据ID删除书签
// @Description 根据ID删除书签
// @Tags 后台管理 - 书签管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "书签ID"
// @Success 200 {object} utils.Response "删除成功"
// @Router /admin/bookmarks/{id} [delete]
func AdminDeleteBookmarkById(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "书签ID格式错误")
		return
	}

	// 先获取书签以确认存在并获取user_id
	var bookmark models.Bookmark
	err = dao.DB.Where("id = ?", uint(id)).First(&bookmark).Error
	if err != nil {
		log.Printf("根据ID获取书签失败: %v", err)
		utils.Error(c, "根据ID获取书签失败")
		return
	}

	// 使用现有的DeleteBookmark函数
	err = dao.DeleteBookmark(uint(id), bookmark.UserID)
	if err != nil {
		log.Printf("删除书签失败: %v", err)
		utils.Error(c, "删除书签失败")
		return
	}

	utils.Success(c, "根据ID删除书签成功", nil)
}

// AdminGetBookmarksByUserId 根据用户ID获取书签
// @Summary 根据用户ID获取书签
// @Description 根据用户ID获取书签
// @Tags 后台管理 - 书签管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param userId path string true "用户ID"
// @Success 200 {object} utils.Response "获取成功"
// @Router /admin/bookmarks/user/{userId} [get]
func AdminGetBookmarksByUserId(c *gin.Context) {
	userIdStr := c.Param("userId")
	userId, err := strconv.ParseUint(userIdStr, 10, 32)
	if err != nil {
		utils.InvalidParams(c, "用户ID格式错误")
		return
	}

	var bookmarks []models.Bookmark

	// 使用DAO的DB直接查询该用户的所有书签
	err = dao.DB.Preload("Category").Where("user_id = ?", uint(userId)).Find(&bookmarks).Error
	if err != nil {
		log.Printf("根据用户ID获取书签失败: %v", err)
		utils.Error(c, "根据用户ID获取书签失败")
		return
	}

	utils.Success(c, "根据用户ID获取书签成功", bookmarks)
}
